//
//  LTRingSDK.h
//  CareRing
//
//  Created by   on 2021/1/6.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "SDkComDefines.h"
#import "CADeviceInfo.h"
#import "CASDKConstant.h"
#import "CAEcgData.h"
#import "CAEcgAlgorithmResults.h"
#import "CAEcgParamObj.h"
#import "CANalgProtocal.h"

#import "CAnAlgGrandActivity.h"
#import "CAnAlgExerData.h"
#import "CAnAlgRealMeasure.h"
#import "CAnAlgRltExerData.h"
NS_ASSUME_NONNULL_BEGIN

@class CABLeService;
@class CAHistoryData;
@class CAHistoryDataSR03;
//@class SRDeviceInfo;

typedef NS_ENUM(UInt8, CAOTA_STATUS_VALUES) {
    // Value zero must not be used !! Notifications are sent when status changes.
    CAOTAR_SRV_STARTED      = 0x01,     // Valid memory device has been configured by initiator. No sleep state while in this mode
    CAOTAR_CMP_OK           = 0x02,     // SPOTA process completed successfully.
    CAOTAR_SRV_EXIT         = 0x03,     // Forced exit of SROTAR service.
    CAOTAR_CRC_ERR          = 0x04,     // Overall Patch Data CRC failed
    CAOTAR_PATCH_LEN_ERR    = 0x05,     // Received patch Length not equal to PATCH_LEN characteristic value
    CAOTAR_EXT_MEM_WRITE_ERR= 0x06,     // External Mem Error (Writing to external device failed)
    CAOTAR_INT_MEM_ERR      = 0x07,     // Internal Mem Error (not enough space for Patch)
    CAOTAR_INVAL_MEM_TYPE   = 0x08,     // Invalid memory device
    CAOTAR_APP_ERROR        = 0x09,     // Application error
    
    // SUOTAR application specific error codes
    CAOTAR_IMG_STARTED      = 0x10,     // SPOTA started for downloading image (SUOTA application)
    CAOTAR_INVAL_IMG_BANK   = 0x11,     // Invalid image bank
    CAOTAR_INVAL_IMG_HDR    = 0x12,     // Invalid image header
    CAOTAR_INVAL_IMG_SIZE   = 0x13,     // Invalid image size
    CAOTAR_INVAL_PRODUCT_HDR= 0x14,     // Invalid product header
    CAOTAR_SAME_IMG_ERR     = 0x15,     // Same Image Error
    CAOTAR_EXT_MEM_READ_ERR = 0x16,     // Failed to read from external memory device
    
};




typedef NS_ENUM(uint32_t, CACS_DEV_MEA_DURA_AND_TM_TYPE) {
    CACS_DEV_MEA_DURA_AND_TM_TYPE_A, // Heart rate/HRV/respiration rate/temperature measurement (心率/HRV/呼吸率/温度测量)
    CACS_DEV_MEA_DURA_AND_TM_TYPE_B,// Spo2 measurement
};

typedef NS_ENUM(uint8_t, CA_NALG_SWIM_POOL_SIZE) {
    CASWIM_POOL_UKONW = 0x00,
    CASWIM_POOL_SIZE_A = 0x01,   // 25m
    CASWIM_POOL_SIZE_B = 0x02,   // 50m
};


typedef NS_ENUM(uint8_t, CAEXER_SUB_CMD) {
    CAEX_STOP = 0,
    CAEX_START = 1,
    CAEX_PAUSE = 2,
    CAEX_CONTINUE = 3,
};




/* about ble device scan and connect */
@protocol CABleScanProtocal <NSObject>

@optional

/// scan device list fresh
/// @param perphelArray  scaned devices
-(void)caScanDeviceDidRefresh:(NSArray<CABLeService *> *)perphelArray;


/// phone ble power state change
/// @param isOn  YES = powerOn NO = pwoerNO
- (void)caBlePowerStateChange:(CBManagerState)state;



@end

/* about ble data translate */
@protocol CABleDataProtocal <NSObject>

- (void)caBleDidConnectPeripheral:(CABLeService*)service;
- (void)caBleDidDisconnectPeripheral:(CABLeService*)service;
- (void)caBleFailConnectPeripheral:(CBPeripheral *)peripheral Error:(NSError *)error;



/// perphel is ready for read write
/// @param service current connect devices
- (void)caBleDeviceDidReadyForReadAndWrite:(CABLeService*)service;



/// Reporting real-time measured values
/// @param hrv :hrv value
/// @param bloodOxygen:Blood oxygen value
/// @param hr: Heart rate value
/// @param status:
- (void)caBleRealtimeHRV:(NSNumber *)hrv BloodOxygen:(NSNumber *)bloodOxygen HeartRate:(NSNumber *)hr Status:(REALTIME_STATUS)status;


/// call back device's battery level and charging state.
/// After the ring is connected to Bluetooth, the ring will automatically report the battery level
/// at a fixed time, and this interface will be automatically called back.
/// @param batteryLevel battery level
/// @param isCharging YES = device is charging
- (void)caBleDeviceBatteryLevel:(NSInteger)batteryLevel IsCharging:(BOOL)isCharging;


/// call back value of device's sn code
/// @param sn sn code
/// @param snData sn original bluetooth message
- (void)caBleSN:(NSString *)sn SnData:(NSData *)snData;


///  Report ring information
/// @param devInfo ring information
- (void)caBleDeviceInfo:(CADeviceInfo *)devInfo;



/// call back realtime skin temperature
/// @param temperature skin temperature Unit(℃)
- (void)caBleDeviceRealtimeTemperature:(NSNumber *)temperature;


/// call back for excute result of sended command
/// @param cmd  sended cmd
/// @param isSucc YES = success
- (void)caBleCmdExcute:(EXCUTED_CMD)cmd Succ:(BOOL)isSucc Reason:(CA_CMD_EXECTE_ERROR_REASON)reason Data:(NSData *)originData;


/// Returns the number of historical data 1
/// @param count Number of historical data
- (void)caBleHistoryDataCount:(NSInteger)count;

/// gain device's cache data time out
- (void)srBleHistoryDataTimeout;


/// Report historical data, one at a time
/// @param SRHistoryDataSR03 Packaged historical data 1
/// @param isComplete YES = translate finish
- (void)caBleHistorySr03Data:(CAHistoryDataSR03 *)hisData IsComplete:(BOOL)isComplete;


/// Callback reporting whether the device is bound
/// @param isBinded -- YES=bound, NO=unbind
- (void)caBleIsBinded:(BOOL)isBinded;





/* OEM AUTH */

/// OEM authentication result callback interface. This interface will be called back after the ring is successfully connected.
/// @param authSucceddful 认证成功=YES
- (void)caBleOEMAuthResult:(BOOL)authSucceddful;

/// 设备每次测量时长上报
/// - Parameter seconds: measuration druration
-(void)caBleMeasureDuration:(NSInteger)seconds;


@optional

// 回调计步阈值 设备协议2.3
//-(void)srBleStepCountThreshold:(uint8_t)threshold;
// 回调ecg波形
-(void)caBleEcgWave:(CAEcgData *)ecgObj;

// ecg+ ppg混合
//-(void)srBleEcgAndPPg:(SrEcgData *)ecgPpgObj;
-(void)caBleEcgAndPPgWave:(CAEcgData *)ecgPpgObj;


// 手指接触
-(void)caBleEcgEcgLeadOn:(BOOL)leadOn;


/// User information reporting
/// - Parameters:
///   - gender:  0 male, 1 female
///   - ageYear: range 1-115
///   - height:  in mm, range 1200-3000
///   - weight:  in kg, range 30-200
-(void)caBleUsrInfoFromoDev:(NSUInteger)gender
                Age:(NSUInteger)ageYear
              Height:(NSUInteger)height
                     Weight:(NSUInteger)weight;


/// Call back the measurement duration and interval set in the ring
/// - Parameters:
///   - meaType: See definition of CS_DEV_MEA_DURA_AND_TM_TYPE
///   - meaduraNoSleep: Measured duration of non-sleep period
///   - meaIntervNoSleep: Measurement interval during non-sleep period
///   - meaduraInSleep: Measured duration during sleep
///   - meaIntervInSleep: Measurement interval during sleep
-(void)caBleNALGDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType MeaDuraofNoSlepPerd:(uint32_t)meaduraNoSleep MeaIntervOfNoSlepPerd:(uint32_t)meaIntervNoSleep
      MeaDuraofInSlepPerd:(uint32_t)meaduraInSleep MeaIntervInNoSlepPerd:(uint32_t)meaIntervInSleep;

/// Reporting algorithm type 0-linkgtop algorithm 1-new algorithm
-(void)caBleNALGalgorithmType:(uint8_t)algorithmType;


/// Report the number of activity detection/swimming/sleep history data
/// - Parameters:
///   - count: The amount of data
///   - minUUid: The minimum uuid of the data reported this time
///   - maxUUid: The maximum uuid of the data reported this time
-(void)caBleHisCntOfActivityAndSwimAndSleep:(NSUInteger)count MinUUid:(uint32_t)minUUid MaxUUid:(uint32_t)maxUUid;

// Callback Report activity detection/exercise/new historical data/body temperature historical data/sleep data
-(void)caBleNalgDeviceMeasurHinstoryData:(id<CANalgProtocal>)dataObj;

// Real-time reporting of exercise data
-(void)caBleNalgRealtimeWorkoutData:(CAnAlgRltExerData *)nalgExerRltData;

// The activity summary data accumulated during the callback day
-(void)caBleLastActivity:(CAnAlgGrandActivity*)activity;

/** CM **/


@end


@protocol CAOTAProtocal <NSObject>

/// ota error callback
/// @param errorCode error code
-(void)caOtaError:(CAOTA_STATUS_VALUES)errorCode;

/// OTA completed
/// @param isSuccessful  YES = successful
-(void)caOtaFinish:(BOOL)isSuccessful;

/// OTA upgrade progress
/// @param progress percentage. Range (0-1)
-(void)caOtaUpdateProgress:(float)progress;

@end



@interface CARingSDK : NSObject

@property(weak, nonatomic)id<CABleScanProtocal> blescanDelegate;
@property(weak, nonatomic)id<CABleDataProtocal> bleDataDelegate;
@property(weak, nonatomic)id<CAOTAProtocal> bleOtaDelegate;  // ota 代理回调对象

+(instancetype)instance;

// 没有别的用, 就是初始化一下sdk
-(void)registWithCompanyArray:(NSArray<NSString *>  * _Nullable )cpArray;


/// Set the key and secret used for ecg calculation
/// - Parameters:
///   - key: key
///   - secret: secret
-(void)registECGKey:(NSString *)key Secret:(NSString *)secret;


/// Determine whether the key and secret have been set
-(BOOL)hasECGKeyAndSecret;

-(void)setBroadCastAnalyCids:(NSArray<NSArray<NSNumber *> *> *)cidArray;

-(NSString *)sdkVersion;

-(NSString *)netKey;

-(NSString *)signStringWith:(NSString *)sn MacAddr:(NSString *)mac;

// iOS ble state
- (CBManagerState)bleCenterManagerState;

-(void)startBleScanWithOption:(NSDictionary * _Nullable)option;
-(void)stopBleScan;
-(void)connectDevice:(CABLeService *)device;
-(void)disconnectCurrentService;

-(CAEcgParamObj *)ecgParamObj;


// The currently connected ring object
-(CABLeService *)currentDevice;

/// Notify the sdk of internally connected or disconnected devices
/// @param peripheralService  SRBLeService instance
-(void)setCurrentPeripheralService:(CABLeService* _Nullable)peripheralService;


/// Enable heart rate/blood oxygen + HRV measurement.  Once turned on, the ring will continue measuring until a stop command is sent or the Bluetooth connection is disconnected.
/// /// will callback from "-caBleRealtimeHRV:BloodOxygen:HeartRate:Status:" and "-(void)caBleNALGRealMeasu:(CAnAlgRealMeasure *)realMeasurData"
/// - Parameters:
///   - both: NO = Heart rate measurement mode, YES = Heart rate + blood oxygen simultaneous measurement mode
///   - isStart: NO=off   yes=on
-(void)functionOxygenAndHrvBoth:(BOOL)both IsOpen:(BOOL)isStart;



/// send cmd to power off device
-(void)functionShutDownDevice;


/// send cmd to reboot device
-(void)functionRebootDevice;

/// get device's battery
/// "- (void)caBleDeviceBatteryLevel:(NSUInteger)batteryLevel IsCharging:(BOOL)isCharging" will
/// call back
-(void)functionGetDeviceBattery;

/// get skin temperature
-(void)functionGetTemperatureOnce;

/// Restore your ring to factory settings.
-(void)functionDeviceReset;


/// get device's SN code
/// "- (void)caBleSN:(NSString *)sn SnData:(NSData *)snData" will call back.
/// "- (void)caBleIsBinded:(BOOL)isBinded" will call back.
/// "- (void)caBleOEMAuthResult:(BOOL)authSucceddful;" will call back
-(void)functionGetDeviceSN;

/// get device's infomation
/// “- (void)caBleDeviceInfo:(SRDeviceInfo *)devInfo” will call back
-(void)functionGetDeviceInfo;

/// blood oxygen measuring setting
/// @param startHor start hour, range in [0 23]
/// @param startMin start minute, range in [0 59]
/// @param startSecond start second, range in [0 59]
/// @param endHor end hour, range in [0 23]
/// @param endMin end minute, range in [0 59]
/// @param endSec end second, range in [0 59]
/// @param interval uint:minute
/// @param isOn switch YES = turn on
-(BOOL)functionSettingOxygenMeasure:(NSUInteger)startHor StartMin:(NSUInteger)startMin StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec Interval:(NSUInteger)interval IsOn:(BOOL)isOn;



/// setting heart rate measure interval and skin temperature measure interval
/// @param hrInterval heart rate interval
/// @param skinTemperatureInterval skin temperature measure interval
/// @param isOn YES = turn on
-(void)functionSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn;


/// get device's cache history data
/// “- caBleHistoryDataCount:”will call back
/// retrun YES = cmd send successful  retrun NO = the last history data process is translating
-(BOOL)functionGetHistoryData;

/// clear device's history data cache
-(void)functionClearDeviceHistoryCache;


/// Get historical data directly without first getting the number of historical data
-(void)functionGetHistoryDataOnlyData;

/// Clear the protection status of the last synchronized data
-(void)functionRsetTranslatingHistoryState;


/// Device activation status settings
/// @param bind YES = bind device NO = unbine device
-(void)functionSetBindeDevice:(BOOL)bind;


/// Set the ring's OEM verification switch
/// @param on :YES = turn on, NO = turn off
-(void)functionSetOEMAuthSwitch:(BOOL)on;



/// Get the duration of each measurement that the device has set
/// "-caBleMeasureDuration: " will call back
-(void)functionGetDeviceMeasureDuration;


/// Set the duration of each measurement of the device
/// - Parameter duration: duration of each measurement, uint:second
-(void)functionSetDeviceMeasureDuration:(NSInteger)duration;

/// ecg measurement on and off
/// - Parameter on: YES= Turn on , NO = Turn off
/// - Parameter paramObj : Parameters required for measurement
/// - Parameter isFilterWave: YES= Use device ecg algorithm
-(BOOL)functionECGMeasure:(BOOL)on Param:(CAEcgParamObj * _Nullable)paramObj DispSrc:(BOOL)isFilterWave;



/// Sync your phone's time to your ring
/// - Parameter date: date
-(void)functionSyncTime:(NSDate *)date;


/**  About OTA **/

/// Start ota to upgrade the ring firmware
/// Will call back the method declared in SROTAProtocal
/// - Parameter fileUrl: Device firmware image
-(void)functionStartOta:(NSURL *)fileUrl;

/**  About OTA **/


/// Set user information
/// - Parameters:
///   - gender: Gender: 0 male, 1 female
///   - ageYear: Age: range 1-115
///   - height: Height: in mm, range 1200-3000
///   - weight: Weight: in kg, range 30-200
-(BOOL)functionSetUsrInfoToDev:(NSUInteger)gender
                           Age:(NSUInteger)ageYear
                         Height:(NSUInteger)height
                        Weight:(NSUInteger)weight;


/// Get user information
/// Callback from the following api: "caBleUsrInfoFromoDev:Age:Height:Weight:"
-(BOOL)functionGetUsrInfoFromDev;

/// Get the latest events(获取最新活动),Callback from interface "-caBleLastActivity:"
-(BOOL)functionGetLastActivity;

/// Get the number of activity detection/swimming/sleep history data (获取活动检测/游泳/睡眠历史数据数量)
/// Callback interface:"caBleHisCntOfActivityAndSwimAndSleep:MinUUid:MaxUUid:"
-(BOOL)functionGetHistoryCntOfActvtyDtctAndSwimAndSleepHisty;

/// Get activity detection/swimming/sleep history data (获取活动检测/游泳/睡眠历史数据)
/// Callback interface: caBleNalgDeviceMeasurHinstoryData:
///  The types of reports that will be issued include:(0x5b下发以后上报的类型:)
/// CAHistoryDataNALG       // 0xc1
/// CAnAlgAutoDetecActivity // 0xc3
/// CAnAlgAutoDetecSWim     // 0xc4
/// CAnAlgExerData          // 0xc5
/// CAnAlgSwimSumData       // 0x0xc6
/// CAnAlgSwimLapData       // 0x0xc7
/// CAnAlgSleep             // 0xc9
/// CAnAlgGrandActivity     // 0xca
/// CAnAlgExerVitalSignsData  // 0xcc
-(BOOL)functionGetHstryDataOfActvtyDetectAndSwimAndSlep; // 0x5B


/// Get part of activity detection/swimming/sleep history data (获取活动检测/游泳/睡眠历史数据)
/// Callback interface: caBleNalgDeviceMeasurHinstoryData:
///  The types of reports that will be issued include:(0x5b下发以后上报的类型:)
/// CAHistoryDataNALG       // 0xc1
/// CAnAlgAutoDetecActivity // 0xc3
/// CAnAlgAutoDetecSWim     // 0xc4
/// CAnAlgExerData          // 0xc5
/// CAnAlgSwimSumData       // 0x0xc6
/// CAnAlgSwimLapData       // 0x0xc7
/// CAnAlgSleep             // 0xc9
/// CAnAlgGrandActivity     // 0xca
/// CAnAlgExerVitalSignsData  // 0xcc
/// - Parameters: maxUUid The maximum index of the data uuid that needs to be obtained
-(BOOL)functionGetHstryDataOfActvtyDetectAndSwimAndSlepMaxUUid:(uint32_t)maxUUid;


/// Clear activity history data.(清空活动历史数据)
-(BOOL)functionCleanActivityHistory;

/// Set the measurement interval and duration of the new Algorithm device
/// call back: "caBleNALGDevMeaDuration:MeaDuraofNoSlepPerd:MeaIntervOfNoSlepPerd:MeaDuraofInSlepPerd: MeaIntervInNoSlepPerd:"
/// - Parameters:
///   - meaType:Measurement type 0-heart rate/HRV/respiration rate/temperature measurement 1-blood oxygen measurement
///   - meaduraNoSleep: The measured duration of the non-sleep period
///   - meaIntervNoSleep: Measurement interval during non-sleep period
///   - meaduraInSleep: Measured duration of sleep periods
///   - meaIntervInSleep: Measurement interval during sleep
-(BOOL)functionSetNalgDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType MeaDuraofNoSlepPerd:(uint32_t)meaduraNoSleep MeaIntervOfNoSlepPerd:(uint32_t)meaIntervNoSleep
                       MeaDuraofInSlepPerd:(uint32_t)meaduraInSleep MeaIntervInNoSlepPerd:(uint32_t)meaIntervInSleep;

/// Get the measurement interval and duration of the new Algorithm device
/// - Parameters:
/// - meaType: Measurement type 0-heart rate/HRV/respiration rate/temperature measurement 1-blood oxygen measurement.
/// callback:"caBleNALGDevMeaDuration:MeaDuraofNoSlepPerd:MeaIntervOfNoSlepPerd:MeaDuraofInSlepPerd: MeaIntervInNoSlepPerd:"
-(BOOL)functionGetNalgDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType;



///  Start exercise
/// - Parameters:
///   - execType: Types of Exercise
///   - sizeType: Pool length, only valid when the type is swimming, for other types of sports, fill in SWIM_POOL_UKONW
///   - duraMins: Estimated duration of exercise, uint: minute
-(BOOL)functionStartNalgExerciseWithType:(NALG_EXERCISE_TYPE)execType PoolSize:(CA_NALG_SWIM_POOL_SIZE)sizeType DurationMins:(uint16_t)duraMins;

/// Keep exercising
-(BOOL)functionContinueNalgExercise;

/// Pause your workout
-(BOOL)functionPauseNalgExercise;

/// Stop exercising
-(BOOL)functionStopNalgExercise;




/// Switch to report activity data during exercise
/// After it is turned on, "-(void)caBleNalgRealtimeWorkoutData:" will continue to call back until a command is sent to turn off the report or Bluetooth is disconnected
/// - Parameter on: YES=turn on NO = off
-(BOOL)functionNalgRealtimeReportDurinExerciseSwitch:(BOOL)on;

///Switch ring ppg algorithm
/// - Parameter algorithmType: 0-Proprietary algorithm、1-Three-party algorithm
-(BOOL)functionNalgSetDeviceAlgorithm:(uint8_t)algorithmType;


/// Get the current ppg algorithm of the ring
-(BOOL)functionNalgGetDeviceAlgorithm;


/* CM */

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@end

NS_ASSUME_NONNULL_END
